Skip to content

Cumulitive update - #71

Merged
Gromwud merged 11 commits into
ITMO-NSS-team:mainfrom
Gromwud:main
May 20, 2026
Merged

Cumulitive update#71
Gromwud merged 11 commits into
ITMO-NSS-team:mainfrom
Gromwud:main

Conversation

@Gromwud

@Gromwud Gromwud commented May 20, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Gromwud and others added 11 commits May 7, 2026 15:13
ndl_update replaces the per-call deepcopy(levels) with a shallow
[list(lvl) for lvl in levels]; only the inner level lists are mutated
(append, slice), so cloning every SoEq/Term/Factor on each individual
inserted into the Pareto layers was pure overhead. Also hoists the
two check_dominance comprehensions out of the per-moving-set-element
branch so each direction is computed once instead of up to four times.

TFPool.create_with_var converts the bare while True over family
sampling into a bounded for-loop that raises RuntimeError on pool
exhaustion (was a silent crash or spin when families.remove(family)
ran against an already-removed entry).

MOEADD's per-call print statements in marriageSolutionAssignment,
ParetoLevels.set_weights, and the obj_fun length probe are gated
behind global_var.verbose.show_iter_idx or converted to warnings.warn
so a default run no longer floods stdout with debug arrays.
…haustion

Bounded the three remaining unbounded retry loops over the structure-
mutation hot path -- they were the canonical "spin on a constrained
pool" hazard from feedback-structure-dedup:

  * Equation.__init__ term-fill loop now bounded (max_iter=100) and
    BREAKS out of the outer slot loop on exhaustion. The pool that
    just refused to yield a unique signature will not become un-
    exhausted on the next slot, so further attempts only waste cycles
    or risk introducing a duplicate downstream.
  * Equation.add_random_term now returns bool: False when terms_number
    is already reached or when the 10-attempt pool sample never finds
    a unique signature. Callers must branch on the False to stop
    looping. The previous or/and inversion left the function a silent
    no-op; the cap (terms_number) prevents the 10x caller in
    EquationMutation.apply from pushing equations past the metaparameter.
  * TermParameterMutation.apply (singleobjective): while True ->
    for _ in range(100); drops the "ENTERING LOOP" / "checking presence"
    debug prints; warns once on exhaustion. Same shape as the
    multiobjective sibling.

Wired the Equation.terms_labels and terms_labels_without_power
properties through the already-declared
_terms_labels_cache / _terms_labels_without_power_cache slots; the
infrastructure existed (15 _invalidate_label_cache() call sites, slot
declarations, reset hooks) but the properties recomputed
unconditionally. Added invalidations at every Term-level mutation /
crossover site that bypasses the Equation API:

  * TermMutation and TermParameterMutation in singleobjective and
    multiobjective mutations.py (8 invalidation points)
  * EquationMutation crossover + EquationExchangeCrossover in both
    flavors of variation.py
  * EquationMutation.apply (multi) now breaks the 10x add_random_term
    loop the moment the helper returns False, mirroring the rule
    "exhaustion stops further structure growth" pinned in the feedback
    memory.

Characterization test was previously pinning the OLD (intentionally
disabled) no-cache contract; replaced with two tests that pin the new
behaviour -- first access populates _terms_labels_cache, second access
returns the identical frozenset, _invalidate_label_cache drops it.

26/26 tests pass; LV smoke-run failure ("Equation has duplicate terms")
that the previous build hit was caused by the same add_random_term
overshoot and is fixed here.
Cumulative work in progress on the EPDE core engine, grouped together
because the diffs are interleaved across these files:

  * SoEqRightPartSelector gains a bidirectional convergence pass:
    forward sequential RPS pre-scrub + a second pass that re-scrubs
    each equation against the others' already-selected RPS, fixing
    the LV-style leak where eq for u kept dv/dx0 as a non-target term.
    _scrub_conflicting_terms and EqRightPartSelector get bounded
    loops + duplicate-term assert at the entry point.
  * L2LRFitness (WAPE) and VWSRSparsity (PhysicsInformedLasso, CV-
    weighted) wired in as the NEW pipeline; GramSetup precomputed
    once outside RFE outer loop.
  * OffspringUpdater in moeadd_specific cleaned up; mutation /
    offspring attempt counters consolidated.
  * MOEADD population constructor, strategy, single-criterion strategy:
    threading of fitness_cls / sparsity_cls / use_pic through the
    EpdeSearch -> MOEADDDirector.use_baseline path so the three
    NEW-pipeline axes are independently selectable.
  * supplementary: GramSetup + sliding-window weight helpers
    consumed by L2LRFitness.
Each per-system <sys>_thesis_run.py was a Python file mixing
declarative state (name, truth equations, outdir, data_fun_pow,
early_stop_on_truth) with imperative state (load_data,
build_extra_tokens). Split into:

  projects/thesis/configs/<sys>.yaml      (declarative, 14 systems)
  projects/thesis/adapters/<sys>.py       (load_data + optional
                                           build_extra_tokens, 14 systems)
  projects/thesis/thesis_runner.py        (gains load_config(yaml) and a
                                           run_smoke `outdir=` kwarg that
                                           lands tagged sweeps under
                                           results/<tag>/<sys>/)
  projects/thesis/run.py                  ("python run.py lv --reps 30
                                           --outdir test_v2")
  projects/thesis/run_ablation.py         (same CLI, defaults
                                           --pipelines to the 6 off-
                                           diagonal cells of the 2x2x2)
  projects/thesis/thesis_metrics.py       (unchanged, copied)
  projects/thesis/thesis_aggregate.py     (new --root flag; glob updated
                                           to results/*/*.json)
  projects/thesis/thesis_ablation_aggregate.py
                                          (same; recognises all 8 cells)

burgers_sln_100.csv added because the new burgers_inviscid adapter
references it; otherwise a fresh clone breaks.

.gitignore: per-rep result JSONs under projects/thesis/results/ and the
two aggregator summary JSONs are regenerated outputs -- gitignored so
fresh clones don't inherit ~half a million lines of historical run
data. Existing JSONs stay on disk; aggregators run against them as
before.

The 18 legacy <sys>_thesis_run.py / <sys>_ablation_run.py scripts and
the 4 shared modules at projects/pic/data/ root were never tracked in
git, so this commit introduces only additions.
Replace the trig-only `freq`-stripping branch in `Term.factors_labels`
and the matching defensive code in `EqRightPartSelector.simplify_equation`
with a uniform `Factor.structural_label` that bucketises continuous-
tolerance params (e.g. trig `freq`) via `equality_ranges`. Same
quantization powers `factors_labels_without_power` for the simplify
common-factor scan. `cache_label` is unchanged and continues to key
the tensor cache.

No behavioural change for the thesis 14 systems: every system uses a
narrow `freq=(v-eps, v+eps)` interval, so all sampled freq values land
in bucket 0 and produce the same structural identity as the prior
freq-stripping logic.
`import deepxde` prints a multi-line backend banner ("Using backend:
pytorch ...") on first load. The eager `from .deepxde_integration
import DeepXDEAdapter` in `epde/integrate/__init__.py` and the
top-level import in `fitness.py` meant any `import epde` triggered
that banner even when no DeepXDE solver is in use (e.g. the legacy
L2 / L2LR fitness paths).

Drop the eager imports; expose `DeepXDEAdapter` via a PEP 562
`__getattr__` on `epde.integrate` so the name still resolves on first
access, but the banner only fires when DeepXDE is actually requested
(via `DeepXDEBasedFitness.apply()`'s existing lazy import at line
436).
@Gromwud
Gromwud merged commit a3f8700 into ITMO-NSS-team:main May 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant